package com.meetingshow.commu.uiservice;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.groups.Default;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import weibo4j.Status;
import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;

import com.meetingshow.common.base.service.model.QueryResults;
import com.meetingshow.common.base.uiservice.BaseUIServiceImp;
import com.meetingshow.common.base.uiservice.exception.BaseUIServiceException;
import com.meetingshow.common.validator.RemoveValidator;
import com.meetingshow.common.validator.UpdateValidator;
import com.meetingshow.commu.dao.model.QuestionPO;
import com.meetingshow.commu.service.IQuestionService;
import com.meetingshow.commu.service.model.QuestionQueryParas;
import com.meetingshow.commu.uiservice.model.QuestionQueryParasVO;
import com.meetingshow.commu.uiservice.model.QuestionVO;
import com.meetingshow.meeting.dao.model.TopicPO;
import com.meetingshow.meeting.service.ITopicService;
import com.meetingshow.privilege.dao.model.UserPO;
import com.meetingshow.privilege.service.IUserService;
import com.meetingshow.utils.BaseUtil;
import com.meetingshow.weibo.dao.model.WeiboPO;
import com.meetingshow.weibo.service.IWeiboService;
import com.meetingshow.weibo.service.model.WeiboQueryParas;

public class UIQuestionServiceImp extends BaseUIServiceImp implements
        IUIQuestionService {

    public final static Logger logger = Logger
            .getLogger(UIQuestionServiceImp.class);

    private IQuestionService questionService;
    private ITopicService topicService;
    private IUserService userService;
    private IWeiboService weiboService;

    /**
     * @return the questionService
     */
    public IQuestionService getQuestionService() {
        return questionService;
    }

    /**
     * @param questionService
     *            the questionService to set
     */
    public void setQuestionService(IQuestionService questionService) {
        this.questionService = questionService;
    }

    public ITopicService getTopicService() {
        return topicService;
    }

    public void setTopicService(ITopicService topicService) {
        this.topicService = topicService;
    }

    public IUserService getUserService() {
        return userService;
    }

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    public IWeiboService getWeiboService() {
        return weiboService;
    }

    public void setWeiboService(IWeiboService weiboService) {
        this.weiboService = weiboService;
    }

    @Override
    public Integer saveQuestion(QuestionVO questionVO)
            throws BaseUIServiceException {

        if (!BaseUtil.objectNotNull(questionVO)) {
            this.throwValidaterException("questionVO is null.");
        }
        
        questionVO.setCreateTime(new Date());

        validateThrowEx(questionVO);
        
        //验证话题是否存在
        TopicPO topicPO = validateTopicExist(questionVO.getTopicId());
        QuestionPO questionPO = questionVO.toQuestionPO();
        questionPO.setTopicName(topicPO.getTopicName());

        //验证提问者是否存在
        validateUserExist(questionVO.getFromUserId(), "FromUser");
        
        //验证被提回者是否存在
        validateUserExist(questionVO.getToUserId(), "ToUser");
        
        try {
            Integer questionId = getQuestionService().saveQuestion(questionPO);
            questionVO.setQuestionId(questionId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        //把问题发送到微博
        Status status = sendStatus(questionPO);

        if (status != null) {
            questionPO.setStatusId(String.valueOf(status.getId()));
            try {
                getQuestionService().updateQuestion(questionPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
        
        return questionVO.getQuestionId();
    }

    @Override
    public void updateQuestion(QuestionVO questionVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(questionVO)) {
            this.throwValidaterException("questionVO is null.");
        }

        validateThrowEx(questionVO, Default.class, UpdateValidator.class);

        QuestionQueryParas questionQueryParas = new QuestionQueryParas();
        questionQueryParas.setQuestionId_e(String.valueOf(questionVO
                .getQuestionId()));

        QueryResults<QuestionPO> questionQueryResults = null;
        try {
            questionQueryResults = getQuestionService().queryQuestion(
                    questionQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        if (QueryResults.resultsListNotNull(questionQueryResults)) {
            QuestionPO persistQuestionPO = questionQueryResults
                    .getResultList().get(0);
            persistQuestionPO.setContent(questionVO.getContent());

            try {
                getQuestionService().updateQuestion(persistQuestionPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }

    @Override
    public void removeQuestion(QuestionVO questionVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(questionVO)) {
            this.throwValidaterException("questionVO is null.");
        }

        validateThrowEx(questionVO, RemoveValidator.class);

        QuestionQueryParas questionQueryParas = new QuestionQueryParas();
        questionQueryParas.setQuestionId_e(String.valueOf(questionVO
                .getQuestionId()));

        QueryResults<QuestionPO> questionQueryResults = null;
        try {
            questionQueryResults = getQuestionService().queryQuestion(
                    questionQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        if (QueryResults.resultsListNotNull(questionQueryResults)) {
            QuestionPO persistQuestionPO = questionQueryResults
                    .getResultList().get(0);
            try {
                getQuestionService().removeQuestion(persistQuestionPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }
    
    @Override
    public QuestionVO loadQuestionById(Integer questionId)
            throws BaseUIServiceException {
        if (questionId == null)
            this.throwValidaterException("questionId is null.");
        
        QuestionPO questionPO = null;
        try {
            questionPO = getQuestionService().loadQuestionById(questionId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (questionPO == null)
            return null;
        else
            return new QuestionVO(questionPO);
    }

    @Override
    public QueryResults<QuestionVO> queryQuestion(
            QuestionQueryParasVO questionQueryParasVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(questionQueryParasVO)) {
            this.throwValidaterException("questionQueryParasVO is null.");
        }

        validateThrowEx(questionQueryParasVO);

        QueryResults<QuestionPO> questionPOQueryResults = null;
        try {
            questionPOQueryResults = getQuestionService()
                    .queryQuestion(
                            questionQueryParasVO.toQuestionQueryParas());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        QueryResults<QuestionVO> questionVOQueryResults = new QueryResults<QuestionVO>();
        List<QuestionVO> questionVOList = new ArrayList<QuestionVO>();
        if (QueryResults.resultsListNotNull(questionPOQueryResults)) {
            for (QuestionPO questionPO : questionPOQueryResults
                    .getResultList()) {
                if (BaseUtil.objectNotNull(questionPO)) {
                    questionVOList.add(new QuestionVO(questionPO));
                }
            }
        }

        questionVOQueryResults.setFirstResultNo(questionPOQueryResults
                .getFirstResultNo());
        questionVOQueryResults.setResultsPerGroup(questionPOQueryResults
                .getResultsPerGroup());
        questionVOQueryResults.setResultList(questionVOList);
        questionVOQueryResults.setTotalResultsNum(questionPOQueryResults
                .getTotalResultsNum());

        return questionVOQueryResults;
    }

    /**
     * 验证话题是否存在
     * @param topicId
     * @return
     * @throws BaseUIServiceException
     */
    private TopicPO validateTopicExist(Integer topicId) throws BaseUIServiceException {
        TopicPO topicPO = null;
        
        try {
            topicPO = getTopicService().loadTopicById(topicId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (topicPO == null)
            throw new BaseUIServiceException("Topic does not exist.");
        else
            return topicPO;
    }
    
    /**
     * 验证用户是否存在
     * @param userId
     * @param validateName
     * @return
     * @throws BaseUIServiceException
     */
    private UserPO validateUserExist(Integer userId, String validateName) throws BaseUIServiceException {
        UserPO userPO = null;
        try {
            userPO = getUserService().loadUserById(userId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (userPO == null)
            throw new BaseUIServiceException(validateName + " does not exist.");
        else
            return userPO;
    }
    
    /**
     * 把问题发送到微博
     * @return
     */
    private Status sendStatus(QuestionPO questionPO) {
        TopicPO topicPO = null;
        try {
            topicPO = getTopicService().loadTopicById(questionPO.getTopicId());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
        
        String toWeiboName = null;
        if (StringUtils.isBlank(questionPO.getToWeiboName())) {
            // 查询被提问人的微博信息
            WeiboPO toWeiboPO = getWeiboByUserId(String.valueOf(questionPO.getToUserId()));
            Weibo weibo = new Weibo();
            try {
                User user = weibo.showUser(toWeiboPO.getWeiboId());
                toWeiboName = user.getScreenName();
            } catch (WeiboException e) {
                logger.error(e.getMessage(), e);
            }
        } else {
            toWeiboName = questionPO.getToWeiboName();
        }

        StringBuilder weiboContent = new StringBuilder();
        weiboContent
                .append("#")
                .append(topicPO.getMeeting().getName())
                .append(" ")
                .append(topicPO.getTopicName())
                .append("#")
                .append(StringUtils.isNotBlank(toWeiboName) ? "@" + toWeiboName
                        + " " : "").append(questionPO.getContent());

        WeiboPO weiboPO = getWeiboByUserId(String.valueOf(questionPO.getFromUserId()));
        Weibo weibo = new Weibo();
        AccessToken accessToken = new AccessToken(weiboPO.getAccessToken(),
                weiboPO.getAccessTokenSecret());
        weibo.setOAuthAccessToken(accessToken);
        try {
            Status status = weibo.updateStatus(weiboContent.toString());
            return status;
        } catch (WeiboException e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }
    
    private WeiboPO getWeiboByUserId(String userId) {
        WeiboQueryParas weiboQueryParas = new WeiboQueryParas();
        weiboQueryParas.setUserId_e(String.valueOf(userId));
        QueryResults<WeiboPO> wbQueryResults = null;
        try {
            wbQueryResults = getWeiboService().queryWeibo(weiboQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        if (!QueryResults.resultsListNotNull(wbQueryResults)) {
            return null;
        } else {
            return wbQueryResults.getResultList().get(0);
        }
    }
}
